// *****************************************************************************
//
// Copyright (c) 2015, Southwest Research Institute® (SwRI®)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Southwest Research Institute® (SwRI®) nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL Southwest Research Institute® BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// *****************************************************************************

#ifndef MAPVIZ_PLUGINS__STRING_PLUGIN_H_
#define MAPVIZ_PLUGINS__STRING_PLUGIN_H_


#include <mapviz/mapviz_plugin.h>

#include <QObject>
#include <QString>
#include <QColor>
#include <QWidget>
#include <QGLWidget>
#include <QPainter>
#include <QFont>
#include <QStaticText>

#include <rclcpp/rclcpp.hpp>

#include <marti_common_msgs/msg/string_stamped.hpp>
#include <std_msgs/msg/string.hpp>

#include <string>

// QT autogenerated files
#include "ui_string_config.h"

namespace mapviz_plugins
{
class StringPlugin : public mapviz::MapvizPlugin
{
  Q_OBJECT

public:
  enum Anchor {
    TOP_LEFT,
    TOP_CENTER,
    TOP_RIGHT,
    CENTER_LEFT,
    CENTER,
    CENTER_RIGHT,
    BOTTOM_LEFT,
    BOTTOM_CENTER,
    BOTTOM_RIGHT
  };

  enum Units {
    PIXELS,
    PERCENT
  };

  StringPlugin();
  ~StringPlugin() override = default;

  bool Initialize(QGLWidget* canvas) override;
  void Shutdown() override {}

  void Draw(double x, double y, double scale) override;
  void Paint(QPainter* painter, double x, double y, double scale) override;

  void Transform() override {}

  void LoadConfig(const YAML::Node& node, const std::string& path) override;
  void SaveConfig(YAML::Emitter& emitter, const std::string& path) override;

  QWidget* GetConfigWidget(QWidget* parent) override;

  bool SupportsPainting() override
  {
    return true;
  }

  void SetText(const QString& text);

protected:
  void PaintText(QPainter* painter);
  void PrintError(const std::string& message) override;
  void PrintInfo(const std::string& message) override;
  void PrintWarning(const std::string& message) override;

protected Q_SLOTS:
  void SelectColor();
  void SelectFont();
  void SelectTopic();
  void TopicEdited();
  void SetAnchor(QString anchor);
  void SetUnits(QString units);
  void SetOffsetX(int offset);
  void SetOffsetY(int offset);

private:
  Ui::string_config ui_;
  QWidget* config_widget_;

  std::string topic_;
  rmw_qos_profile_t qos_;
  Anchor anchor_;
  Units units_;
  int offset_x_;
  int offset_y_;

  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr string_sub_;
  rclcpp::Subscription<marti_common_msgs::msg::StringStamped>::SharedPtr string_stamped_sub_;
  bool has_message_;
  bool has_painted_;

  QColor color_;
  QFont font_;
  QStaticText message_;

  void connectCallback(const std::string& topic, const rmw_qos_profile_t& qos);
  std::string AnchorToString(Anchor anchor);
  std::string UnitsToString(Units units);

  static const char* ANCHOR_KEY;
  static const char* COLOR_KEY;
  static const char* FONT_KEY;
  static const char* OFFSET_X_KEY;
  static const char* OFFSET_Y_KEY;
  static const char* TOPIC_KEY;
  static const char* UNITS_KEY;
};
}  // namespace mapviz_plugins


#endif   // MAPVIZ_PLUGINS__STRING_PLUGIN_H_
